/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pb138.bookinfo;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.google.api.client.googleapis.services.GoogleKeyInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.books.Books;
import com.google.api.services.books.Books.Volumes.List;
import com.google.api.services.books.model.Volume;
import com.google.api.services.books.model.Volumes;

/**
 *
 * @author Siliarus
 */
public class BookInformationSearcherImpl implements BookInformationSearcher {
    
    JsonFactory jsonFactory = new JacksonFactory();
    
    
    
    public Volume searchForBook (String query) {
        Volume book = null;
        
        // Set up Books client.
        final Books books = Books.builder(new NetHttpTransport(), jsonFactory)
        .setApplicationName("Google-BooksSample/1.0")
        .setJsonHttpRequestInitializer(new GoogleKeyInitializer(ClientCredentials.KEY))
        .build();
        
        
        // Set isbn query string and filter only full results.
        query = "isbn:" + query;
        System.out.println("Query: [" + query + "]");
        try {
            List volumesList = books.volumes().list(query);
            
            // Execute the query.
            Volumes volumes = volumesList.execute();
            if (volumes.getTotalItems() == 0 || volumes.getItems() == null || volumes.getTotalItems() > 1) {
                //Probably illegal ISBN, no or multiple result were found
            return null;
            }
            // Convert a List with only one book (due to unique ISBN) into a Volume
            book = volumes.getItems().get(0);
            
        } catch (java.net.UnknownHostException e) {
        	throw new RuntimeException("Cannot connect to Internet!");
        } catch (IOException ex) {
            Logger.getLogger(BookInformationSearcherImpl.class.getName()).log(Level.SEVERE, "Error while trying to list the query results", ex);
        }
        return book;
    }
    
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        
        String isbn = "0439023483";
        //String isbn = "0590353403";
        BookInformationSearcherImpl searcher = new BookInformationSearcherImpl();
        Volume myBook = searcher.searchForBook(isbn);
        if (myBook == null) {
            System.out.println("There is a problem with query");
        } else {
            System.out.println(searcher.bookTitle(myBook));
            System.out.println(searcher.bookRating(myBook));
            System.out.println(searcher.bookAuthors(myBook));
            System.out.println(searcher.bookDescription(myBook));
        }
        URL review = searcher.reviewURL(myBook);
        
        System.out.println("Review link: " + review);
        
        
        /**
        String id = myBook.getId();
        System.out.println(myBook.getSaleInfo().getIsEbook());
        System.out.println(myBook.getSaleInfo().setCountry("US"));
        System.out.println(myBook.getSaleInfo().getSaleability());
        System.out.println(myBook.getSaleInfo().getBuyLink());
        System.out.println(myBook.getSaleInfo().getRetailPrice());*/
        
    }

    
    public ArrayList<String> bookAuthors(Volume book) {
        if (book == null) {
            throw new IllegalArgumentException("Volume is null");
        }
        ArrayList <String> authors = new ArrayList<String>();
        authors = (ArrayList<String>) book.getVolumeInfo().getAuthors();
        if (authors == null || authors.isEmpty()) {
            authors.add("No authors were found");
        }
        return authors;
    }
    
    public Double bookRating (Volume book) {
        if (book == null) {
            throw new IllegalArgumentException("Volume is null");
        }
        return book.getVolumeInfo().getAverageRating();
    }
    
    public String bookDescription (Volume book) {
        if (book == null) {
            throw new IllegalArgumentException("Volume is null");
        }
        String information = book.getVolumeInfo().getDescription();
        if (information == null) {
            return "No information found";
        }
        return information;
    }
    
    public String bookTitle (Volume book) {
        if (book == null) {
            throw new IllegalArgumentException("Volume is null");
        }
        String title = book.getVolumeInfo().getTitle();
        if (title == null) {
            return "No title found";
        }
        return title;
    }
    

    public URL reviewURL(Volume book) {
        URL url = null;
        String review = book.getVolumeInfo().getInfoLink();
        if (review == null) {
            return url;
        }
        int i = review.indexOf("&source");
        String remake = review.substring(0, i);        
        try {
            
            url = new URL (remake.concat("&hl=cs&sitesec=reviews"));
        } catch (MalformedURLException ex) {
            Logger.getLogger(BookInformationSearcherImpl.class.getName()).log(Level.SEVERE, "Problem while creating URL", ex);
        }
        return url;
    }
    
    public ArrayList<String> getReviews(URL url) {
        ArrayList<String> reviews = new ArrayList<String>();
        
        Document doc = null;
        try {
            doc = Jsoup.connect(url.toString()).ignoreContentType(true).userAgent("Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52").get();
        } catch (IOException ex) {
            throw new IllegalArgumentException(ex);
        }
        
        Elements elemList = doc.select("p[dir=ltr]");
        for (int i = 0; i < elemList.size(); i++) {
            Element el = (Element) elemList.get(i);
            String review = el.text();
            review = review.replace("<br>", "\n");
            reviews.add(review);
        }
       return reviews;
    }
    
}
